package com.ly.emp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ly.common.core.bean.R;
import com.ly.common.core.exception.ServiceException;
import com.ly.common.core.utils.BaseUtils;
import com.ly.emp.bean.dto.HubTeamDTO;
import com.ly.emp.bean.dto.TeamResultOrderDTO;
import com.ly.emp.bean.dto.TeamResultOrderDetailDTO;
import com.ly.emp.bean.vo.HubTeamWorkVO;
import com.ly.emp.bean.vo.HubTreeVO;
import com.ly.emp.constant.EmpConstants;
import com.ly.emp.constant.EmpErrorConstants;
import com.ly.emp.entity.HubTeamWork;
import com.ly.emp.entity.HubTeamWorkType;
import com.ly.emp.entity.TeamResultOrder;
import com.ly.emp.entity.TeamResultOrderDetail;
import com.ly.emp.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 实现类-工单工分登记
 *
 * @author luoyun
 * @Date: 2023-05-18
 */
@Service
@RequiredArgsConstructor
public class HubTeamResultOrderServiceImpl implements IHubTeamResultOrderService {

    private final IEmpCommonService teamCommonService;
    private final IHubTeamWorkTypeService hubTeamWorkTypeService;
    private final IHubTeamWorkService hubTeamWorkService;
    private final IEpmTeamRationRegService teamRationRegService;
    private final IEpmTeamRationRegDetailService teamRationRegDetailService;

    @Override
    public R getList(TeamResultOrderDetail entity) {
        String orgCode = entity.getOrgCode();
        if (StrUtil.isBlank(orgCode)) {
            return R.fail(EmpErrorConstants.NO_TEAM);
        }
        List<String> isIntensificationList = teamCommonService.getIsIntensificationListByOrgCode(orgCode);
        List<TeamResultOrderDetail> list = teamRationRegDetailService.list(
                new LambdaQueryWrapper<TeamResultOrderDetail>()
                        .in(TeamResultOrderDetail::getOrgCode, isIntensificationList)
                        .eq(TeamResultOrderDetail::getPeriodCode, entity.getPeriodCode())
                        .orderByAsc(TeamResultOrderDetail::getOrgCode)
        );
        return R.ok(list);
    }

    @Override
    public R getPage(TeamResultOrder entity, Page<TeamResultOrder> page) {
        String periodCode = entity.getPeriodCode();
        String orgCode = entity.getOrgCode();
        if (StrUtil.isBlank(periodCode)) {
            return R.fail(EmpErrorConstants.NO_PERIOD);
        }
        if (StrUtil.isBlank(orgCode)) {
            return R.fail(EmpErrorConstants.NO_TEAM);
        }
        List<String> isIntensificationList = teamCommonService.getIsIntensificationListByOrgCode(orgCode);
        IPage<TeamResultOrder> pageList = teamRationRegService.page(page,
                new LambdaQueryWrapper<TeamResultOrder>()
                        .in(TeamResultOrder::getOrgCode, isIntensificationList)
                        .eq(TeamResultOrder::getPeriodCode, periodCode)
                        .like(StrUtil.isNotBlank(entity.getPsnName()), TeamResultOrder::getPsnName, entity.getPsnName())
                        .ge(StrUtil.isNotBlank(entity.getStartTime()), TeamResultOrder::getEndDate, entity.getStartTime())
                        .le(StrUtil.isNotBlank(entity.getEndTime()), TeamResultOrder::getEndDate, entity.getEndTime())
                        .orderByDesc(TeamResultOrder::getSysCreateDate)
        );
        return R.ok(pageList);
    }

    @Override
    public R<List<HubTreeVO>> getWorkList(HubTeamWork entity) {
        String orgCode = entity.getOrgCode();
        String periodCode = entity.getPeriodCode();
        if (StrUtil.isBlank(orgCode)) {
            return R.fail(EmpErrorConstants.NO_TEAM);
        }
        if (StrUtil.isBlank(periodCode)) {
            return R.fail(EmpErrorConstants.NO_PERIOD);
        }
        return this.getWorkListByOrgCode(orgCode, periodCode);
    }

    public R<List<HubTreeVO>> getWorkListByOrgCode(String orgCode, String periodCode) {
        List<HubTeamWorkType> list = hubTeamWorkTypeService.list(
                new LambdaQueryWrapper<HubTeamWorkType>()
                        .eq(HubTeamWorkType::getOrgCode, orgCode)
                        .orderByAsc(HubTeamWorkType::getDisplayOrder)
        );
        // 指标类型
        List<HubTeamWork> workList = hubTeamWorkService.list(
                new LambdaQueryWrapper<HubTeamWork>()
                        .eq(HubTeamWork::getOrgCode, orgCode)
                        .eq(HubTeamWork::getPeriodCode, periodCode)
                        .orderByAsc(HubTeamWork::getDisplayOrder)
        );
        List<HubTreeVO> workListVos = new ArrayList<>();
        if (CollUtil.isNotEmpty(workList)) {
            workList.stream().forEach(n -> {
                HubTreeVO vo = new HubTreeVO();
                vo.setId(n.getId());
                vo.setKey(n.getId());
                vo.setCode(n.getWorkItemCode());
                vo.setTitle(n.getWorkItemName());
                vo.setParentCode(n.getWorkTypeCode());
                vo.setIsRation(true);
                vo.setIsLeaf(true);
                vo.setDesc(String.valueOf(n.getStandardValue()));
                workListVos.add(vo);
            });
        }
        // 级联数据封装
        List<HubTreeVO> workTypeConfigVOS = selectChildren("0", list, workListVos);
        return R.ok(workTypeConfigVOS);
    }

    /**
     * 级联数据封装
     *
     * @param parentCode
     * @param list
     * @param workListVos
     * @return
     */
    private List<HubTreeVO> selectChildren(String parentCode, List<HubTeamWorkType> list, List<HubTreeVO> workListVos) {
        List<HubTreeVO> treeVOS = new ArrayList<>();
        list.stream()
                .filter(n -> parentCode.equals(n.getLeaderWorkTypeCode()))
                .forEach(n -> {
                    HubTreeVO vo = new HubTreeVO();
                    vo.setId(n.getId());
                    vo.setKey(n.getId());
                    vo.setCode(n.getWorkTypeCode());
                    vo.setTitle(n.getWorkTypeName());
                    vo.setParentCode(n.getWorkTypeCode());
                    vo.setIsRation(false);
                    vo.setIsLeaf(false);
                    vo.setDisabled(true);
                    // = BeanUtil.copyProperties(n,HubTreeVO.class);
                    List<HubTreeVO> childrenList = selectChildren(n.getWorkTypeCode(), list, workListVos);
                    // 没有子类型，代表是叶子类型，叶子类型，需要封装对应的指标
                    if (CollUtil.isNotEmpty(childrenList)) {
                        vo.setChildren(childrenList);
                    } else {
                        List<HubTreeVO> vos = workListVos.stream()
                                .filter(work -> n.getWorkTypeCode().equals(work.getParentCode())).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(vos)) {
                            vos.forEach(work -> work.setChildren(null));
                            vo.setChildren(vos);
                        } else {
                            // 无指标，则直接为null
                            vo.setChildren(null);
                        }
                    }
                    treeVOS.add(vo);
                });
        return treeVOS;
    }

    @Override
    public R<HubTeamWorkVO> getWorkDetail(String id) {
        HubTeamWork entity = hubTeamWorkService.getById(id);
        HubTeamWorkVO vo = BeanUtil.copyProperties(entity, HubTeamWorkVO.class);
        return R.ok(vo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R save(TeamResultOrderDTO dto) {
        String workId = dto.getWorkId();
        if(StrUtil.isEmpty(workId)){
            throw new ServiceException("请先选择工作项");
        }
        HubTeamWork hubTeamWork = hubTeamWorkService.getById(workId);
        if(hubTeamWork==null){
            throw new ServiceException("找不到工作项信息");
        }
        String suitUnit = BaseUtils.getSuitUnit();
        TeamResultOrder order = BeanUtil.toBean(dto, TeamResultOrder.class);
        order.setWorkName(hubTeamWork.getWorkItemName());
        order.setWorkTypeName(hubTeamWork.getWorkTypeName());
        order.setSuitUnit(suitUnit);

        List<TeamResultOrderDetailDTO> details = dto.getDetails();
        if (CollUtil.isNotEmpty(details)) {
            String psnNameList = details.stream().map(TeamResultOrderDetailDTO::getPsnName).collect(Collectors.joining(","));
            String psnNumList = details.stream().map(TeamResultOrderDetailDTO::getPsnNum).collect(Collectors.joining(","));
            order.setPsnName(psnNameList);
            order.setPsnNum(psnNumList);
        }
        // 保存主表
        boolean b = teamRationRegService.saveOrUpdate(order);
        List<TeamResultOrderDetail> detailsList = new ArrayList<>();
        if (CollUtil.isNotEmpty(details)) {
            teamRationRegDetailService.remove(
                    new LambdaQueryWrapper<TeamResultOrderDetail>()
                            .eq(TeamResultOrderDetail::getOrderId, order.getId())
            );
            details.stream().forEach(n -> {
                TeamResultOrderDetail orderDetail = BeanUtil.copyProperties(n, TeamResultOrderDetail.class);
                orderDetail.setOrderId(order.getId());
                orderDetail.setOrgCode(dto.getOrgCode());
                orderDetail.setOrgName(dto.getOrgName());
                orderDetail.setPeriodCode(dto.getPeriodCode());
                orderDetail.setSuitUnit(suitUnit);
                detailsList.add(orderDetail);
            });
            // 保存详情数据
            teamRationRegDetailService.saveOrUpdateBatch(detailsList);
        }
        return b ? R.ok(true, "保存成功") : R.fail("保存失败");
    }

    @Override
    public R<TeamResultOrderDTO> getWorkCheckInDetail(String id) {
        if (StrUtil.isBlank(id)) {
            return R.fail(EmpErrorConstants.RESULT_NO_RATIONREG_KEY);
        }
        // 根据录入模式，得到对应的积分详情
        TeamResultOrder teamResultOrder = teamRationRegService.getById(id);
        TeamResultOrderDTO vo = BeanUtil.toBean(teamResultOrder, TeamResultOrderDTO.class);
        List<TeamResultOrderDetail> list = teamRationRegDetailService.list(
                new LambdaQueryWrapper<TeamResultOrderDetail>()
                        .eq(TeamResultOrderDetail::getSuitUnit, BaseUtils.getSuitUnit())
                        .eq(TeamResultOrderDetail::getOrderId, vo.getId()));
        List<TeamResultOrderDetailDTO> listVo = BeanUtil.copyToList(list, TeamResultOrderDetailDTO.class);
        vo.setDetails(listVo);
        return R.ok(vo);
    }

    @Override
    public R<TeamResultOrderDTO> getWorkCheckInDetailForTwoDimensional(HubTeamDTO dto) {
        List<TeamResultOrder> list = teamRationRegService.list(
                new LambdaQueryWrapper<TeamResultOrder>()
                        .eq(TeamResultOrder::getOrgCode, dto.getOrgCode())
                        .eq(TeamResultOrder::getAddMode, EmpConstants.RESULT_ADD_MODE_TWO_DIMENSIONAL)
                        .eq(TeamResultOrder::getPeriodCode, dto.getPeriodCode())
        );
        if (CollUtil.isNotEmpty(list)) {
            TeamResultOrder teamResultOrder = list.get(0);
            TeamResultOrderDTO vo = BeanUtil.toBean(teamResultOrder, TeamResultOrderDTO.class);
            List<TeamResultOrderDetail> detailList = teamRationRegDetailService.list(
                    new LambdaQueryWrapper<TeamResultOrderDetail>()
                            .eq(TeamResultOrderDetail::getOrderId, teamResultOrder.getId()));
            if (CollUtil.isNotEmpty(detailList)) {
                List<TeamResultOrderDetailDTO> details = new ArrayList<>();
                detailList.stream().forEach(n -> {
                    TeamResultOrderDetailDTO detail = BeanUtil.copyProperties(n, TeamResultOrderDetailDTO.class);
                    details.add(detail);
                });
                vo.setDetails(details);
            }
            return R.ok(vo);
        }
        return R.ok();
    }

    @Override
    public R deleteResultOrder(String id) {
        if (StrUtil.isBlank(id)) {
            return R.fail(EmpErrorConstants.NO_ID);
        }
        boolean b = teamRationRegService.removeById(id);
        teamRationRegDetailService.remove(
                new LambdaQueryWrapper<TeamResultOrderDetail>()
                        .eq(TeamResultOrderDetail::getOrderId, id)
        );
        return b ? R.ok(true, "删除成功") : R.fail("删除失败");
    }
}
